package g11.testutil;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import g11.actionutil.VisitationContentUtil;
import g11.actionutil.VisitationContentUtilImpl;
import g11.dao.AppointmentDAO;
import g11.dao.AppointmentDAOImpl;
import g11.dao.DrugDAO;
import g11.dao.DrugDAOImpl;
import g11.dao.EmployeeDAO;
import g11.dao.EmployeeDAOImpl;
import g11.dao.PatientDAO;
import g11.dao.PatientDAOImpl;
import g11.dao.PrescriptionDAO;
import g11.dao.PrescriptionDAOImpl;
import g11.dao.VisitationContentDAO;
import g11.dao.VisitationContentDAOImpl;
import g11.dao.VisitationDAO;
import g11.dao.VisitationDAOImpl;
import g11.model.Appointment;
import g11.model.Drug;
import g11.model.Employee;
import g11.model.Patient;
import g11.model.Prescription;
import g11.model.Visitation;
import g11.model.VisitationContent;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class testVisitationContentUtil {

	@Test
	public void testingVisitationContentUtil() throws Exception {
		// create 2 doctor objects
		Employee employee1 = new Employee();
		employee1.setUsername("penny");
		employee1.setPassword("1234");
		Byte type = 1;
		employee1.setType(type);
		employee1.setName("Penny Money");
		employee1.setDepartment("Surgery");
		employee1.setTitle("Surgery Doctor");

		Employee employee2 = new Employee();
		employee2.setUsername("leo");
		employee2.setPassword("1234");
		employee2.setType(type);
		employee2.setName("Leo Ben");
		employee2.setDepartment("Inpatient");
		employee2.setTitle("Inpatient Doctor");

		// persist doctors, get two persisted employee objects: doctorPenny,
		// doctorLeo
		EmployeeDAO employeeDao = new EmployeeDAOImpl();
		Integer employeeId1 = employeeDao.createEmployee(employee1);
		Integer employeeId2 = employeeDao.createEmployee(employee2);
		Employee doctorPenny = new Employee();
		Employee doctorLeo = new Employee();
		doctorPenny = employeeDao.getEmployeeById(employeeId1);
		doctorLeo = employeeDao.getEmployeeById(employeeId2);
		assertNotNull(doctorPenny);
		assertNotNull(doctorLeo);

		// create 2 patient objects: patientNancy, patientBell
		Patient patientNancy = new Patient();
		patientNancy.setUsername("nancy");
		patientNancy.setName("Nancy Ken");
		patientNancy.setPassword("1234");
		Byte userType = 0;
		patientNancy.setType(userType);
		patientNancy.setPhone("519-888-8888");
		patientNancy.setAddress("77 Weber Street");
		patientNancy.setOhip("111");
		patientNancy.setSin("111");
		patientNancy.setCurrentHealth("Diabetes.");

		Patient patientBell = new Patient();
		patientBell.setUsername("bell");
		patientBell.setName("Bell Alex");
		patientBell.setPassword("1234");
		patientBell.setType(userType);
		patientBell.setPhone("519-555-6666");
		patientBell.setAddress("12 King Street");
		patientBell.setOhip("222");
		patientBell.setSin("222");
		patientBell.setCurrentHealth("High Blood Pressure");

		// persist patients, get two persisted patient objects: patientNancy,
		// patientBell
		PatientDAO patientDao = new PatientDAOImpl();
		Integer patientNancyId = patientDao.createPatient(patientNancy);
		Integer patientBellId = patientDao.createPatient(patientBell);
		patientNancy = patientDao.getPatientById(patientNancyId);
		patientBell = patientDao.getPatientById(patientBellId);
		assertNotNull(patientNancy);
		assertNotNull(patientBell);

		// create drug object 2
		Drug drugAdvil = new Drug();
		drugAdvil.setDrugName("Advil");
		Byte drugType = 1;
		drugAdvil.setType(type);

		Drug drugTylenol = new Drug();
		drugTylenol.setDrugName("Tylenol");
		drugTylenol.setType(type);

		// persist durgs, get two persisted drug objects: drugAdvil, drugTylenol
		DrugDAO drugDao = new DrugDAOImpl();
		Integer drugAdvilId = drugDao.createDrug(drugAdvil);
		Integer drugTylenolId = drugDao.createDrug(drugTylenol);
		drugAdvil = drugDao.getDrugById(drugAdvilId);
		drugTylenol = drugDao.getDrugById(drugTylenolId);
		assertNotNull(drugAdvil);
		assertNotNull(drugTylenol);

		// create two appointment object
		// doctorPenny with patientNancy
		Appointment appDPennyPNancy = new Appointment();
		appDPennyPNancy.setDoctor(doctorPenny);
		appDPennyPNancy.setPatient(patientNancy);
		// doctorLeo with patientBell
		Appointment appDLeoPBell = new Appointment();
		appDLeoPBell.setDoctor(doctorLeo);
		appDLeoPBell.setPatient(patientBell);

		// persistent the two appointment: get two persisted appointment
		// objects: appDPennyPNancy, appDLeoPBell
		AppointmentDAO appointmentDao = new AppointmentDAOImpl();
		Integer appDLeoPBellId;
		appDLeoPBellId = appointmentDao.createAppointment(appDLeoPBell);
		Integer appDPennyPNancyId;
		appDPennyPNancyId = appointmentDao.createAppointment(appDPennyPNancy);
		appDPennyPNancy = appointmentDao.getAppointmentById(appDPennyPNancyId);
		appDLeoPBell = appointmentDao.getAppointmentById(appDLeoPBellId);
		assertNotNull(appDPennyPNancy);
		assertNotNull(appDLeoPBell);

		// create two visitationContent object through appointment (the
		// visiation objects will be automatically created)
		VisitationContentUtil visitationContentUtil = new VisitationContentUtilImpl();
		VisitationContentDAO visitationContentDAO = new VisitationContentDAOImpl();
		VisitationDAO visitationDAO = new VisitationDAOImpl();
		Visitation vDLeoPBell = new Visitation();
		Integer vcDLeoPBellId;
		VisitationContent vcDLeoPBell = new VisitationContent();
		vcDLeoPBell.setDiagnosis("Bell is Illed");
		vcDLeoPBell.setTreatment("Bell eat drug");
		vcDLeoPBell.setComment("Bell will be fine");

		VisitationContent vcDPennyPNancy = new VisitationContent();
		vcDPennyPNancy.setDiagnosis("Nancy has Headache");
		vcDPennyPNancy.setTreatment("Nancy eat Advil");
		vcDPennyPNancy.setComment("Nancy will be fine");

		// create one prescription for the visitationcontent
		Prescription prescriptionAdvil = new Prescription();
		prescriptionAdvil.setDrug(drugAdvil);
		prescriptionAdvil.setDosage("1 pill per day");
		vcDLeoPBell.getPrescriptionSet().add(prescriptionAdvil);
		vcDPennyPNancy.getPrescriptionSet().add(prescriptionAdvil);
		assertTrue(vcDLeoPBell.getPrescriptionSet().size() > 0);
		assertTrue(vcDPennyPNancy.getPrescriptionSet().size() > 0);

		// persist one visitationContent vcDLeoPBell;
		vcDLeoPBellId = visitationContentUtil
				.createVisitationContentFromAppointment(appDLeoPBell,
						vcDLeoPBell);
		vcDLeoPBell = visitationContentDAO
				.getVisitationContentById(vcDLeoPBellId);
		vDLeoPBell = visitationDAO.getCurrentVersionOfVisitation(vcDLeoPBell
				.getVisitation().getVisitationId());
		// persist another visitationContent vcDPennyPNancy
		Integer vcDPennyPNancyId;
		vcDPennyPNancyId = visitationContentUtil
				.createVisitationContentFromAppointment(appDPennyPNancy,
						vcDPennyPNancy);
		vcDPennyPNancy = visitationContentDAO
				.getVisitationContentById(vcDPennyPNancyId);
		Visitation vDPennyPNancy = new Visitation();
		vDPennyPNancy = visitationDAO
				.getCurrentVersionOfVisitation(vcDPennyPNancy.getVisitation()
						.getVisitationId());

		// verify the result of
		// "visitationContentUtil.createVisitationContentFromAppointment"
		assertNotNull(vcDLeoPBell);
		assertNotNull(vDLeoPBell);
		assertEquals(vcDLeoPBell.getVersion(), vDLeoPBell.getCurrentVersion());
		assertEquals(vcDLeoPBell.getDiagnosis(), "Bell is Illed");
		assertNotNull(vcDPennyPNancy);
		assertNotNull(vDPennyPNancy);
		assertEquals(vcDPennyPNancy.getVersion(),
				vDPennyPNancy.getCurrentVersion());
		assertEquals(vcDPennyPNancy.getDiagnosis(), "Nancy has Headache");
		PrescriptionDAO prescriptionDAO = new PrescriptionDAOImpl();
		List<Prescription> prescriptionList = new ArrayList<Prescription>();
		prescriptionList = prescriptionDAO
				.getPrescriptionByVisitationContent(vcDLeoPBell);
		assertTrue(!prescriptionList.isEmpty());
		assertEquals((Integer) prescriptionList.get(0).getDrugId(),
				(Integer) drugAdvil.getDrugId());
		List<Prescription> prescriptionPennyNancyList = new ArrayList<Prescription>();
		prescriptionPennyNancyList = prescriptionDAO
				.getPrescriptionByVisitationContent(vcDPennyPNancy);
		assertTrue(!prescriptionPennyNancyList.isEmpty());
		assertEquals((Integer) prescriptionPennyNancyList.get(0).getDrugId(),
				(Integer) drugAdvil.getDrugId());

		// execute updateVisitationContent and verify the result
		// 1) change comment
		vcDLeoPBell.setComment("Bell has recoverd");
		// add one more prescription
		Prescription prescriptionTylenol = new Prescription();
		prescriptionTylenol.setDrug(drugTylenol);
		prescriptionTylenol.setDosage("2 pill per day");
		vcDLeoPBell.getPrescriptionSet().add(prescriptionTylenol);
		// using updateVisitationContent to update vcDLeoPBell
		Integer vcDLeoPBellv2Id;
		vcDLeoPBellv2Id = visitationContentUtil
				.updateVisitationContent(vcDLeoPBell);
		vDLeoPBell = visitationDAO.getCurrentVersionOfVisitation(vDLeoPBell
				.getVisitationId());
		VisitationContent vcDLeoPBellv2 = new VisitationContent();
		vcDLeoPBellv2 = visitationContentDAO
				.getCurrentVisitationContent(vDLeoPBell);
		// Visitation vDLeoPBellv2 = new Visitation();
		vDLeoPBell = visitationDAO.getCurrentVersionOfVisitation(vcDLeoPBellv2
				.getVisitation().getVisitationId());
		List<Prescription> prescriptionListv2 = new ArrayList<Prescription>();
		prescriptionListv2 = prescriptionDAO
				.getPrescriptionByVisitationContent(vcDLeoPBellv2);
		assertEquals(vcDLeoPBellv2.getComment(), "Bell has recoverd");
		assertEquals(vcDLeoPBellv2.getVersion(), vDLeoPBell.getCurrentVersion());
		assertTrue(vcDLeoPBellv2.getPrescriptionSet().size() == 2);
		assertTrue(prescriptionListv2.size() == 2);
		assertEquals((Integer) prescriptionListv2.get(0).getDrugId(),
				(Integer) drugAdvil.getDrugId());
		assertEquals((Integer) prescriptionListv2.get(1).getDrugId(),
				(Integer) drugTylenol.getDrugId());

		// test getLatestVisitationContentByDrugForDoctor
		List<VisitationContent> vcAdvilLeoList = new ArrayList<VisitationContent>();
		List<VisitationContent> vcTylenolLeoList = new ArrayList<VisitationContent>();
		vcAdvilLeoList = visitationContentUtil
				.getLatestVisitationContentByDrugForDoctor(drugAdvil, doctorLeo);
		vcTylenolLeoList = visitationContentUtil
				.getLatestVisitationContentByDrugForDoctor(drugTylenol,
						doctorLeo);
		assertTrue(vcAdvilLeoList.size() > 0);
		assertTrue(vcTylenolLeoList.size() > 0);
		assertEquals(vcAdvilLeoList.get(0).getVersion(),
				vDLeoPBell.getCurrentVersion());
		assertEquals(vcTylenolLeoList.get(0).getVersion(),
				vDLeoPBell.getCurrentVersion());

		// test getLatestVisitationContentByKeywordForDoctor
		List<VisitationContent> vcDLeoKeywordIlledList = new ArrayList<VisitationContent>();
		vcDLeoKeywordIlledList = visitationContentUtil
				.getLatestVisitationContentByKeywordForDoctor(doctorLeo,
						"Illed", 0);
		assertEquals(vcDLeoKeywordIlledList.get(0).getVersion(),
				vDLeoPBell.getCurrentVersion());

		List<VisitationContent> vcDPennyKeywordAdvilList = new ArrayList<VisitationContent>();
		vcDPennyKeywordAdvilList = visitationContentUtil
				.getLatestVisitationContentByKeywordForDoctor(doctorPenny,
						"Advil", 1);
		assertEquals(vcDPennyKeywordAdvilList.get(0).getVersion(),
				vDPennyPNancy.getCurrentVersion());

		// delete objects
		vcDLeoPBell = visitationContentDAO
				.getVisitationContentById(vcDLeoPBellId);
		vcDLeoPBell = visitationContentDAO
				.getVisitationContentById(vcDLeoPBellId);
		vcDLeoPBellv2 = visitationContentDAO
				.getVisitationContentById(vcDLeoPBellv2Id);
		if (vcDLeoPBell.getPrescriptionSet().size() > 0) {
			for (Prescription tempPrescription : vcDLeoPBell
					.getPrescriptionSet()) {
				if (tempPrescription.getVisitationContentId() != null) {
					prescriptionDAO.deletePrescription(tempPrescription);
				}
			}
		}
		if (vcDLeoPBellv2.getPrescriptionSet().size() > 0) {
			for (Prescription tempPrescription : vcDLeoPBellv2
					.getPrescriptionSet()) {
				if (tempPrescription.getVisitationContentId() != null) {
					prescriptionDAO.deletePrescription(tempPrescription);
				}
			}
		}
		if (vcDPennyPNancy.getPrescriptionSet().size() > 0) {
			for (Prescription tempPrescription : vcDPennyPNancy
					.getPrescriptionSet()) {
				if (tempPrescription.getVisitationContentId() != null) {
					prescriptionDAO.deletePrescription(tempPrescription);
				}
			}
		}

		visitationContentDAO.deleteVisitationContent(vcDLeoPBell);

		visitationContentDAO.deleteVisitationContent(vcDLeoPBellv2);
		visitationContentDAO.deleteVisitationContent(vcDPennyPNancy);
		visitationDAO.deleteVisitation(vDPennyPNancy);
		visitationDAO.deleteVisitation(vDLeoPBell);
		// visitationDAO.deleteVisitation(vDLeoPBellv2);
		appointmentDao.deleteAppointment(appDLeoPBell);
		appointmentDao.deleteAppointment(appDPennyPNancy);
		employeeDao.deleteEmployee(doctorPenny);
		employeeDao.deleteEmployee(doctorLeo);
		patientDao.deletePatient(patientNancy);
		patientDao.deletePatient(patientBell);
		drugDao.deleteDrug(drugAdvil);
		drugDao.deleteDrug(drugTylenol);

	}

}
